<?php

namespace app\services;

use app\traits\Page;
use plugin\admin\app\model\Like;
use plugin\admin\app\model\User;
use plugin\admin\app\model\UserCollect;
use plugin\admin\app\model\UserFollowing;
use plugin\admin\app\model\UserHistory;
use plugin\admin\app\model\UserProfile;
use plugin\admin\app\model\Video;

class VideoService
{
    public static function recommendList($page, $length = 10)
    {
        $offset = ($page - 1) * $length;

        $query = Video::select(['id', 'thumb', 'likes', 'money'])->where('is_recommend', 1)->orderByDesc('created_time');

        $totalCount = (clone $query)->count();
        $list = $query->offset($offset)->limit($length)->get()->toArray();

        foreach ($list as $key=>$item) {
            $list[$key]['thumb'] = full_url($item['thumb']);
        }

        return Page::wrap($totalCount, $page, $length, $list);
    }

    public static function hotList($page, $length = 10)
    {
        return self::search('', $page, $length, ['likes', 'desc']);
    }

    public static function raceList($page, $length = 10)
    {
        $offset = ($page - 1) * $length;

        $query = Video::select(['id', 'thumb', 'likes', 'money'])->where('user_id', 0)->orderByDesc('created_time');

        $totalCount = (clone $query)->count();
        $list = $query->offset($offset)->limit($length)->get()->toArray();

        foreach ($list as $key=>$item) {
            $list[$key]['thumb'] = full_url($item['thumb']);
        }

        return Page::wrap($totalCount, $page, $length, $list);
    }

    public static function followList($page, $length = 10)
    {
        $offset = ($page - 1) * $length;

        $followings = UserFollowing::where('user_id', get_user_id())->get()->toArray();
        $userIds = array_column($followings, 'follow_user_id');

        $query = Video::select(['id', 'thumb', 'likes', 'money'])->whereIn('user_id', $userIds)->orderByDesc('created_time');

        $totalCount = (clone $query)->count();
        $list = $query->offset($offset)->limit($length)->get()->toArray();

        foreach ($list as $key=>$item) {
            $list[$key]['thumb'] = full_url($item['thumb']);
        }

        return Page::wrap($totalCount, $page, $length, $list);
    }

    public static function search($keyword, $page = 1, $length = 10, $order = ['created_time', 'desc'])
    {
        $offset = ($page - 1) * $length;

        $query = Video::select(['id', 'user_id', 'thumb', 'desc'])->where('desc', 'like', "%$keyword%");

        $totalCount = (clone $query)->count();
        $list = $query->offset($offset)->limit($length)->orderBy($order[0], $order[1])->get()->toArray();

        $userIds = array_column($list, 'user_id');
        $users = UserProfile::select(['user_id', 'avatar', 'nickname'])->whereIn('user_id', $userIds)->get()->toArray();
        $users = array_combine(
            array_column($users, 'user_id'),
            array_values($users)
        );

        foreach ($list as $key=>$item) {
            $list[$key]['thumb'] = full_url($item['thumb']);
            $user = $users[$item['user_id']];
            $list[$key]['user_info'] = $user;
        }

        return Page::wrap($totalCount, $page, $length, $list);
    }

    /**
     * 我的作品列表
     *
     * @param $page
     * @param $length
     * @return array
     */
    public static function list($page, $length = 1, $userId = null)
    {
        $userId = $userId ?? get_user_id();

        $offset = ($page - 1) * $length;

        $query = Video::select(['id', 'thumb', 'likes', 'money'])->where('user_id', $userId)->orderByDesc('created_time');

        $totalCount = (clone $query)->count();
        $list = $query->offset($offset)->limit($length)->get()->toArray();

        foreach ($list as $key=>$item) {
            $list[$key]['thumb'] = full_url($item['thumb']);
        }

        return Page::wrap($totalCount, $page, $length, $list);
    }

    /**
     * 作品详情
     *
     * @param $id
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public static function detail($id)
    {
        $video = Video::select(['id', 'thumb', 'video_url', 'likes', 'comments', 'shares', 'collects', 'money', 'user_id', 'desc'])->where('id', $id)->first();

        if (!$video) {
            throw new \Exception('不存在的视频');
        }

        $userInfo = UserProfile::select(['id', 'nickname', 'avatar'])->where('user_id', $video['user_id'])->first();

        $video['thumb'] = full_url($video['thumb']);
        $video['video_url'] = full_url($video['video_url']);

        $video['user_info'] = $userInfo;

        $video['is_following'] = FollowingService::isFollowing($video['user_id']);
        $video['is_like'] = LikeService::isLike($video['id'], Like::TYPE_VIDEO);
        $video['is_collect'] = UserCollectService::isCollect($video['id'], UserCollect::VIDEO);

        UserHistoryService::add(UserHistory::VIDEO, $id);

        return $video;
    }

    public static function add($videoUrl, $desc = '')
    {
        UserProfile::where('user_id', get_user_id())->increment('deploy');

        return Video::insertGetId([
            'user_id' => get_user_id(),
            'video_url' => $videoUrl,
            'desc' => $desc,
            'created_time' => date('Y-m-d H:i:s')
        ]);
    }

    public static function delete($id)
    {
        Video::where('user_id', get_user_id())->where('id', $id)->delete();
        UserProfile::where('user_id', get_user_id())->decrement('deploy');
    }

    public static function follow($id)
    {
        FollowingService::follow($id, function ($loginUserId, $followUserId) {
            UserProfile::where('user_id', $loginUserId)->increment('follow_count');
            UserProfile::where('user_id', $followUserId)->increment('fans_count');
        });
    }

    public static function cancelFollow($id)
    {
        FollowingService::cancelFollow($id, function ($loginUserId, $followUserId) {
            UserProfile::where('user_id', $loginUserId)->decrement('follow_count');
            UserProfile::where('user_id', $followUserId)->decrement('fans_count');
        });
    }

    public static function like($id)
    {
        if (!self::isLike($id)) {
            $video = Video::where('id', $id)->first();
            LikeService::like($id, $video['user_id'], Like::TYPE_VIDEO, function ($id) {
                Video::where('id', $id)->increment('likes', 1);
                $video = Video::where('id', $id)->first();
                UserProfile::where('user_id', $video['user_id'])->increment('like_count');  //视频作者被赞数加1
                UserProfile::where('user_id', get_user_id())->increment('likes');       //点赞者喜欢数加1
            });
        }
    }

    public static function isLike($id)
    {
        return LikeService::isLike($id, Like::TYPE_VIDEO);
    }

    public static function cancelLike($id)
    {
        LikeService::cancelLike($id, Like::TYPE_VIDEO, function ($id, $type) {
            Video::where('id', $id)->decrement('likes', 1);
            $video = Video::where('id', $id)->first();
            UserProfile::where('user_id', $video['user_id'])->decrement('like_count');  //视频作者被赞数减1
            UserProfile::where('user_id', get_user_id())->decrement('likes');       //点赞者喜欢数减1
        });
    }

    public static function collect($id)
    {
        UserCollectService::collect(UserCollect::VIDEO, $id, function($type, $id) {
            Video::where('id', $id)->increment('collects', 1);
            UserProfile::where('user_id', get_user_id())->increment('collects');
        });
    }

    public static function cancelCollect($id)
    {
        UserCollectService::uncollect(UserCollect::VIDEO, $id, function($type, $id) {
            Video::where('id', $id)->decrement('collects', 1);
            UserProfile::where('user_id', get_user_id())->decrement('collects');
        });
    }

    public static function generateThumb($id, $videoPath)
    {
        $relativePath = '/userUpload/' . microtime(true) * 1000 . '.png';
        $outputPath = public_path() . $relativePath;

        $command = "ffmpeg -i {$videoPath} -ss 00:00:01 -vframes 1 $outputPath";
        exec($command);

        Video::where('id', $id)->update(['thumb' => $relativePath]);

    }

}